local ls = require("luasnip")
local s = ls.snippet
local t = ls.text_node
local i = ls.insert_node
local fmt = require("luasnip.extras.fmt").fmt

ls.add_snippets("go", {
    -- Check Error
    s("checke", fmt([[
if err != nil {{
    return err
}}
{}]], {i(1)})),

    -- := operator
    s("a", t(":=")),

    -- Utils NoError
    s("no", fmt([[
if utils.NoError(err) {{
    {}
}}]], {i(1)})),

    -- For range loop
    s("forr", fmt([[
for _, {} := range {} {{
    {}
}}]], {i(1, "v"), i(2, "slice"), i(3, "// code")})),

    -- For i loop
    s("fori", fmt([[
for i := 0; i < {}; i++ {{
    {}
}}]], {i(1, "n"), i(2, "// code")})),

    -- Return Error
    s("re", fmt([[
if err != nil {{
    return err
}}
{}]], {i(1)})),

    -- Check Error with panic
    s("ie", fmt([[
if err != nil {{
    panic(err)
}}
{}]], {i(1)})),

    -- Print
    s("st", fmt([[fmt.Println({})]], {i(1)})),

    -- Function
    s("func", fmt([[
func {}({}) {} {{
    {}
}}]], {
        i(1, "name"),
        i(2, "params"),
        i(3, "return"),
        i(4, "// code"),
    })),

    -- Method
    s("meth", fmt([[
func ({} {}) {}({}) {} {{
    {}
}}]], {
        i(1, "r"),
        i(2, "Receiver"),
        i(3, "name"),
        i(4, "params"),
        i(5, "return"),
        i(6, "// code"),
    })),

    -- Struct
    s("st", fmt([[
type {} struct {{
    {} {} {}
}}]], {
        i(1, "Name"),
        i(2, "field"),
        i(3, "type"),
        i(4, "`json:\"field\"`"),
    })),

    -- Interface
    s("int", fmt([[
type {} interface {{
    {}({}) {}
}}]], {
        i(1, "Name"),
        i(2, "method"),
        i(3, "params"),
        i(4, "return"),
    })),

    -- Test Function
    s("test", fmt([[
func Test{}(t *testing.T) {{
    {}
}}]], {
        i(1, "Name"),
        i(2, "// code"),
    })),

    -- Benchmark Function
    s("bench", fmt([[
func Benchmark{}(b *testing.B) {{
  for i := 0; i < b.N; i++ {{
    {}
  }}
}}]], {
        i(1, "Name"),
        i(2, "// code"),
    })),

    -- Error handling with defer
    s("errdef", fmt([[
defer func() {{
  if err := recover(); err != nil {{
    {}
  }}
}}()]], {
        i(1, "// error handling"),
    })),

    -- go routine
    s("go", fmt([[
go func() {{
    {}
}}()]], {
        i(1, "// code"),
    })),

    -- select case
    s("sel", fmt([[
select {{
case {} <- {}:
    {}
case {} <- {}:
    {}
default:
    {}
}}]], {
        i(1, "v1"),
        i(2, "ch1"),
        i(3, "// code"),
        i(4, "v2"),
        i(5, "ch2"),
        i(6, "// code"),
        i(7, "// code"),
    })),
    -- Log Print
    s("lt", fmt([[log.Println({}){}]], {i(1), i(0)})),
})
